package org.streets.context.internal;

import org.apache.tapestry5.ioc.services.SymbolSource;
import org.streets.context.HiveRegistry;

/**
 * Registry Holder for real implemented ioc containner
 * @author dzb
 */
public final class RegistryHolder implements HiveRegistry {

    private org.apache.tapestry5.ioc.Registry _t5_ioc = null;

    public RegistryHolder(org.apache.tapestry5.ioc.Registry t5 ) {
        _t5_ioc = t5;
    }

    /**
     * Locates a service given just a service interface. A single service must implement the service interface (which
     * can be hard to guarantee). The search takes into account inheritance of the service interface (not the service
     * <em>implementation</em>), which may result in a failure due to extra matches.
     *
     * @param <T>
     * @param serviceInterface the interface the service implements
     * @return the service's proxy
     * @throws RuntimeException if the service does not exist (this is considered programmer error), or multiple
     *                          services directly implement, or extend from, the service interface
     */
    public <T> T service(Class<T> serviceInterface) {
        return _t5_ioc.getService(serviceInterface);
    }

    /**
     * Obtains a service via its unique service id. Returns the service's proxy. The service proxy implements the same
     * interface as the actual service, and is used to instantiate the actual service only as needed (this is
     * transparent to the application).
     *
     * @param <T>
     * @param serviceId        unique Service id used to locate the service object (may contain <em>symbols</em>, which
     *                         will be expanded), case is ignored
     * @param serviceInterface the interface implemented by the service (or an interface extended by the service
     *                         interface)
     * @return the service instance
     * @throws RuntimeException if the service is not defined, or if an error occurs instantiating it
     */
    public <T> T service(String serviceId, Class<T> serviceInterface) {
        return _t5_ioc.getService(serviceId, serviceInterface);
    }
    
    /**
     * Create a proxy for a interfaced Object
     * @param <T>
     * @param interfaceClass
     * @param implementationClass
     * @return
     */
    public <T> T proxy(Class<T> interfaceClass, Class<? extends T> implementationClass) {
        
        return _t5_ioc.proxy(interfaceClass, implementationClass);
    }
    /**
     * 
     * @param symbol
     * @return
     */
    public String symbolValue(String symbol) {
        SymbolSource ss = _t5_ioc.getService(SymbolSource.class);
        return ss.valueForSymbol(symbol);
    }

    public String expandSymbol(String input) {
        SymbolSource ss = _t5_ioc.getService(SymbolSource.class);
        return ss.expandSymbols(input);
    }
    /**
     * 
     */
    public void setupThread() {
        // Do noting, just for pair
    }
    /**
     * Invoked at the end of a request to discard any thread-specific information accumulated during the current
     * request.
     *
     * @see org.apache.tapestry5.ioc.services.PerthreadManager
     * @see org.apache.tapestry5.ioc.services.ThreadCleanupListener
     */
    public void cleanupThread() {
        _t5_ioc.cleanupThread();
    }

    /**
     * Invoked to eagerly load services marked with the {@link EagerLoad} annotation, and to execute all contributions
     * to the Startup service.
     */
    public void startup() {
        _t5_ioc.performRegistryStartup();
    }

    /**
     * Shuts down a Registry instance. Notifies all listeners that the registry has shutdown. Further method invocations
     * on the Registry are no longer allowed, and the Registry instance should be discarded.
     *
     * @see org.apache.tapestry5.ioc.services.RegistryShutdownHub
     * @see org.apache.tapestry5.ioc.services.RegistryShutdownListener
     */
    public void shutdown() {
        try {
           _t5_ioc.shutdown();
        } catch (Exception ex) {
            //
        }
    }
}
